# 用于会话管理的工具函数
import os
import json
import time
import streamlit as st

# 存放页面输入框的缓存文件
CACHE_FILE = "session_cache.json"

# 只放登录态的缓存文件
AUTH_FILE = "auth.json"


def _load_whole():
    path = "session_cache.json"  # 替换为你实际的路径
    if not os.path.exists(path):
        return {}
    try:
        with open(path, 'r', encoding='utf-8') as f:
            return json.load(f)
    except (json.JSONDecodeError, ValueError):
        # 如果 JSON 损坏，返回空 dict
        return {}


def _save_whole(data: dict):
    """整文件覆盖写"""
    with open(CACHE_FILE, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=2, ensure_ascii=False)


# ---------- 供各页面使用的 load / save ----------
def load_session(page_key: str) -> dict:
    """读取指定页面的缓存"""
    return _load_whole().get(page_key, {})


def save_session(page_key: str, data: dict):
    """把 data 写入 page_key 字段"""
    whole = _load_whole()
    whole[page_key] = data
    _save_whole(whole)


def _load_auth():
    if os.path.exists(AUTH_FILE):
        with open(AUTH_FILE, "r", encoding="utf-8") as f:
            return json.load(f)
    return {}


def _save_auth(data: dict):
    with open(AUTH_FILE, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=2)


# 设置登录过期时间
LOGIN_VALID_SECONDS = 24 * 60 * 60

# 预置账号密码（实际项目可放到 st.secrets 或数据库）
USER_CREDENTIALS = {
    "alice": "123456",
    "bob": "abc123",
    "xiaochen": "123456"
}


def init_session():
    auth = _load_auth()
    if auth and auth.get("logged_in", False):
        expire_at = auth.get("login_expire_at", 0)
        if time.time() < expire_at:
            st.session_state.update(auth)
            return  # 已恢复，直接返回

    # 否则初始化默认状态
    st.session_state["logged_in"] = False
    st.session_state["username"] = ""
    st.session_state["login_expire_at"] = None


# ---------- 登录/登出 ----------
def login(username: str, password: str) -> bool:
    """
        返回 True/False 表示登录成功/失败
        username：用户在输入框里敲的名字，字符串。
        password：用户在输入框里敲的密码，字符串。
    """
    if not username or not password:
        return False
    #  USER_CREDENTIALS.get(username) 会去字典里找 键等于 username 的那一项。找到了，就返回对应的密码（值），找不到，返回 None。
    stored_pwd = USER_CREDENTIALS.get(username)
    print(f"[DEBUG] 输入用户:{username}, 输入密码:{password}, 库中密码:{stored_pwd}")
    """
        如果 stored_pwd 刚好等于用户填的 password，就把两条信息写进 Streamlit 的全局会话字典 st.session_state：
        logged_in = True：标记用户已登录。
        username：记住是谁登录的。
        然后返回 True，告诉调用方（login_page.py）“登录成功”。
        否则返回 False，“登录失败”。
    """
    if stored_pwd == password:
        st.session_state["logged_in"] = True
        st.session_state["username"] = username
        # 新增：记录本次登录的过期时间 = 当前时间 + 24 小时
        st.session_state["login_expire_at"] = time.time() + LOGIN_VALID_SECONDS
        #  把当前会话持久化
        _save_auth({
            "logged_in": True,
            "username": username,
            "login_expire_at": st.session_state["login_expire_at"]
        })
        return True
    return False


def logout():
    st.session_state["logged_in"] = False
    st.session_state["username"] = ""
    st.session_state["login_expire_at"] = None
    if os.path.exists(AUTH_FILE):
        os.remove(AUTH_FILE)


# ---------- 鉴权装饰器 ----------
def require_login(func):
    """
    装饰器：如果未登录，强制跳转到登录页（利用 st.stop() 中断后续渲染）。
    用法：
        @require_login
        def main_page():

    在 @require_login 装饰器里增加一步判断：如果当前时间已超过 login_expire_at，则自动调用 logout() 并跳转到登录页面。
    """

    def wrapper(*args, **kwargs):
        # 如果未登录 或 登录已过期 → 强制跳转登录页
        if not st.session_state.get("logged_in", False):
            from streamlit_model.streamlit_common_page.login_page import login_page
            login_page()
            st.stop()

        # 新增：检查过期时间
        expire_at = st.session_state.get("login_expire_at")
        if expire_at is None or time.time() > expire_at:
            logout()  # 先清掉登录态
            from streamlit_model.streamlit_common_page.login_page import login_page
            login_page()
            st.stop()

        return func(*args, **kwargs)

    return wrapper
